package com.rinlink.gateway.jt808.service;

import com.rinlink.gateway.jt808.exception.WebHookPostResponseException;
import com.rinlink.gateway.jt808.exception.WebHookPostTimeoutException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.time.Duration;

@Service
@Slf4j
public class WebHookServiceImpl implements WebHookService{

    private WebClient webClient;

    public WebHookServiceImpl(@Autowired(required = false) WebClient webClient){
        this.webClient = webClient == null ? WebClient.builder().build() : webClient;
    }

    public void push(String url,Object data,int timeoutSeconds){

        if (log.isDebugEnabled())
            log.debug("Push [{}] to {}",data,url);

        push(url,data,String.class)
                .timeout(Duration.ofSeconds(3),Mono.error(new WebHookPostTimeoutException(URI.create(url),data)))
                .subscribe(e->{
                    if (log.isDebugEnabled())
                        log.debug("Push [{}] success",data);
                },e->{
                    if (log.isDebugEnabled())
                        log.warn("Push failed",e);
                });
    }

    @Override
    public <T> Mono<T> push(String url, Object data, Class<T> resp) {
        URI uri = URI.create(url);
        return  webClient
                .post()
                .uri(uri)
                .body(BodyInserters.fromObject(data))
                .retrieve().onStatus(
                        status->status.isError(),
                        (r)-> Mono.error(new WebHookPostResponseException(uri,data,r.statusCode()))
                ).bodyToMono(resp);
    }
}
